package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.recheck.pojo.RecheckAttrRulePojo;
import com.xbongbong.pro.recheck.pojo.RecheckFormRulePojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.RecheckingRuleEntity;
import com.xbongbong.saas.enums.RecheckMatchWayEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @description 查重2.0 重复规则帮助类
 * @author yanglei
 * @date 2022/11/9 14:31
 */
@Component
@Slf4j
public class RecheckingAddRuleHelp {
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;


    /**
     * @description 通过业务类型返回具体重复规则,返回集合
     * @author jiangren.li
     * @date 2022/11/9 14:39
     * @return List<RecheckAttrRulePojo>
     */
    public RecheckAttrRulePojo getRecheckAttrRuleByBusinessType(Integer businessType, RecheckFormRulePojo recheckFormRulePojo){
        try {
            List<RecheckAttrRulePojo> recheckAttrRulePojoList = new ArrayList<>();
            XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
            switch (xbbRefTypeEnum){
                case CUSTOMER_MANAGEMENT:
                    recheckAttrRulePojoList = recheckFormRulePojo.getCustomer();
                    break;
                case CLUE:
                    recheckAttrRulePojoList = recheckFormRulePojo.getClue();
                    break;
                case CONTACT:
                    recheckAttrRulePojoList = recheckFormRulePojo.getContact();
                    break;
                case SALES_OPPORTUNITY:
                    recheckAttrRulePojoList = recheckFormRulePojo.getOpportunity();
                    break;
                default:
                    break;
            }

            if (recheckAttrRulePojoList.size() > 0) {
                return recheckAttrRulePojoList.get(0);
            }
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * @description 获取当前业务所有模板id
     * @author yanglei
     * @date 2022/11/10 16:27
     * @param corpid 公司id
     * @param businessType 业务类型
     * @return List<Long>
     */
    public List<Long> getAllFormIdList(String corpid, Integer businessType) throws XbbException {
        //获取当前业务所有启用的模板
        List<PaasFormEntityExt> enableFormList = paasFormModel.getEnableFormList(corpid, businessType);
        if(CollectionsUtil.isEmpty(enableFormList)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, "当前业务表单模板都没开启");
        }
        return enableFormList.stream().map(PaasFormEntityExt::getId).collect(Collectors.toList());
    }


    /**
     * 查找表单的解释map
     * @author yanglei
     * @date 2022/11/10 16:27
     * @param corpid 公司id
     * @param formId 表单id
     * @return Map<FieldAttrEntity>
     */
    public Map<String, FieldAttrEntity> getExplainMap(Long formId, String corpid) throws XbbException{
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        if(Objects.isNull(explainEntity)){
            log.warn("当前公司id:{},formId:{}",corpid,formId);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(MessageConstant.FORM_EXPLAIN_NOT_EXIST));
        }
        List<FieldAttrEntity> explainList = JSONArray.parseArray(explainEntity.getExplains(), FieldAttrEntity.class);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(explainList.size());
        explainList.forEach(fieldAttrEntity -> explainMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity));
        return explainMap;
    }
    /**
     * @description 获取多个表单模板的字段解释map
     * @author yanglei
     * @date 2023/3/14 22:16
     * @param formIdList
     * @param corpid
     * @return Map<Map<FieldAttrEntity>>
     */
    public Map<Long,Map<String, FieldAttrEntity>> getAllExplainMap(List<Long> formIdList, String corpid) throws XbbException{
        Map<Long,Map<String, FieldAttrEntity>> result = new HashMap<>();
        List<PaasFormExplainEntity> paasFormExplainEntities = paasFormExplainModel.getByFormIdIn(formIdList, corpid);
        if (CollectionsUtil.isNotEmpty(paasFormExplainEntities)){
            for (PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntities) {
                if (Objects.isNull(paasFormExplainEntity)){
                    continue;
                }
                List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                Map<String, FieldAttrEntity> explainMap = explainList.stream().collect(Collectors.toMap(FieldAttrEntity::getAttr, FieldAttrEntity -> FieldAttrEntity));
                result.put(paasFormExplainEntity.getFormId(),explainMap);
            }
        }
        return result;
    }

    /**
     * @description 针对于线索联合查重，从实体中汇总新建不允许重复规则查重该工具规则
     * @author yanglei
     * @date 2022/11/21 19:12
     * @param ruleList 规则实体
     * @param businessType 业务类型
     * @return List<RecheckAttrRulePojo>
     */
    public List<RecheckAttrRulePojo> getClueLinkRecheckAttrRulePojo(List<RecheckFormRulePojo> ruleList,Integer businessType){
        List<RecheckAttrRulePojo> recheckAttrRulePojos = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(ruleList)){
            for (RecheckFormRulePojo formRulePojo : ruleList) {
                RecheckAttrRulePojo attrRulePojo = getRecheckAttrRuleByBusinessType(businessType, formRulePojo);
                if (Objects.nonNull(attrRulePojo)){
                    recheckAttrRulePojos.add(attrRulePojo);
                }
            }
        }
        return recheckAttrRulePojos;
    }
    /**
     * @description 从重复数据中获取被查重字段的值
     * @author yanglei
     * @date 2022/11/22 10:13
     * @param recheckAttrMap 通过哪个字段查出来的 只存在于线索联合查重
     * @param currentDataList 重复数据集合
     * @param attr 被查字段
     * @param subAttr 子表单被查字段
     * @param value 被查字段的值
     * @return List<Object>
     */
    public List<Object> getValueList(Map<Integer, String> recheckAttrMap,List<PaasFormDataEntityExt> currentDataList,List<PaasFormDataEntityExt> contactAndCustomerList,String attr,String subAttr,Object value){
        List<Object> valueList = new ArrayList<>();
        //判断结果中是否有完全匹配的数据
        for (PaasFormDataEntityExt paasFormDataEntityExt : currentDataList) {
            JSONObject data = paasFormDataEntityExt.getData();
            Object clueValue = data.get(attr);
            //流水号宽表字段
            if (Objects.equals(attr, FieldTypeEnum.SERIALNO.getAlias())){
                clueValue = paasFormDataEntityExt.getSerialNo();
            }
            //线索本身业务,查询到当前值
            if (Objects.equals(value, clueValue)) {
                valueList.add(clueValue);
            }
            //当前业务子表单字段匹配,证明是子表单字段查重
            if (StringUtil.isNotEmpty(subAttr)){
                subFormAttrHitValue(valueList,data,attr,subAttr,value);
            }
        }
        if (CollectionsUtil.isNotEmpty(contactAndCustomerList)){
            for (PaasFormDataEntityExt paasFormDataEntityExt : contactAndCustomerList) {
                JSONObject data = paasFormDataEntityExt.getData();
                //线索联合客户和联系人的数据
                if (Objects.nonNull(recheckAttrMap)){
                    String contactLinkAttr = recheckAttrMap.get(XbbRefTypeEnum.CONTACT.getCode());
                    String customerLinkAttr = recheckAttrMap.get(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode());
                    if (Objects.nonNull(contactLinkAttr)){
                        String[] split = contactLinkAttr.split("\\.");
                        if (split.length > 1){
                            subFormAttrHitValue(valueList,data,split[0],split[1],value);
                        }else {
                            if(Objects.equals(value,data.get(split[0]))){
                                valueList.add(data.get(split[0]));
                            }
                        }
                    }
                    if (Objects.nonNull(customerLinkAttr)){
                        String[] split = customerLinkAttr.split("\\.");
                        if (split.length > 1){
                            subFormAttrHitValue(valueList,data,split[0],split[1],value);
                        }else {
                            if(Objects.equals(value,data.get(split[0]))){
                                valueList.add(data.get(split[0]));
                            }
                        }
                    }
                }
            }
        }
        return valueList;
    }
    private void subFormAttrHitValue(List<Object> valueList,JSONObject data,String attr,String subAttr,Object value){
        //子表单字段匹配,证明是子表单字段查重
        JSONArray subForm = data.getJSONArray(attr);
        if (CollectionsUtil.isNotEmpty(subForm)){
            for (Object o : subForm) {
                JSONObject json =  (JSONObject) o;
                Object jsonValue = json.get(subAttr);
                if (Objects.equals(jsonValue,value)){
                    //证明匹配到了
                    valueList.add(jsonValue);
                    break;
                }
            }
        }
    }

    /**
     * @description 判断被查重的字段是否存在查重规则规则里面 - 针对线索联合查重
     * @author yanglei
     * @date 2022/12/5 11:24
     * @param recheckAttrMap 线索联合查重被哪个字段查出来的
     * @param checkToolRule 查重工具规则
     * @param attr 被查的字段
     * @param businessType 业务类型
     * @return Boolean
     */
    public Boolean checkClueJoinAttrExistRecheckTool(Map<Integer, String> recheckAttrMap,List<RecheckFormRulePojo> checkToolRule,String attr,Integer businessType){
        if (CollectionsUtil.isEmpty(checkToolRule)){
            return false;
        }
        for (RecheckFormRulePojo recheckFormRulePojo : checkToolRule) {
            RecheckAttrRulePojo currentRule = getRecheckAttrRuleByBusinessType(businessType, recheckFormRulePojo);
            String currentAttr = Objects.nonNull(currentRule) ? currentRule.getAttr() : "";
            if (Objects.equals(currentAttr,attr)){
                if (Objects.equals(businessType,XbbRefTypeEnum.CLUE.getCode())){
                    RecheckAttrRulePojo contactRule = getRecheckAttrRuleByBusinessType(XbbRefTypeEnum.CONTACT.getCode(), recheckFormRulePojo);
                    RecheckAttrRulePojo customerRule = getRecheckAttrRuleByBusinessType(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), recheckFormRulePojo);
                    String cotactLinkAttr = Objects.nonNull(contactRule) ? contactRule.getLinkAttr() : "";
                    String customerLinkAttr = Objects.nonNull(customerRule) ? customerRule.getLinkAttr() : "";
                    boolean isLinkHit = Objects.equals(cotactLinkAttr,recheckAttrMap.get(XbbRefTypeEnum.CONTACT.getCode()))
                            || Objects.equals(customerLinkAttr,recheckAttrMap.get(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));
                    if(isLinkHit){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * @description  判断被查重的字段是否存在查重规则规则里面
     * @author yanglei
     * @date 2022/12/7 16:02
     * @param checkToolRule
     * @param attr
     * @param businessType
     * @return Boolean
     */
    public Boolean checkAttrExistRecheckToolRule(List<RecheckFormRulePojo> checkToolRule,String attr,Integer businessType){
        if (CollectionsUtil.isEmpty(checkToolRule)){
            return false;
        }
        for (RecheckFormRulePojo recheckFormRulePojo : checkToolRule) {
            RecheckAttrRulePojo currentRule = getRecheckAttrRuleByBusinessType(businessType, recheckFormRulePojo);
            String currentAttr = Objects.nonNull(currentRule) ? currentRule.getAttr() : "";
            if (Objects.equals(currentAttr,attr)){
                return true;
            }
        }
        return false;
    }


    /**
     * @description 初始化默认重复规则
     * @author yanglei
     * @date 2022/11/9 14:39
     * @return RecheckAttrRulePojo
     */
    public RecheckingRuleEntity initDefaultRecheckRuleEntity(Integer businessType){
        long now = DateTimeUtil.getInt();
        RecheckingRuleEntity entity = new RecheckingRuleEntity();
        //列 表单级别规则
        List<RecheckFormRulePojo> noRepeatRule = new ArrayList<>();
        List<RecheckFormRulePojo> checkToolRule = new ArrayList<>();
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        entity.setCorpid(StringConstant.DEFAULT_CORPID);
        entity.setFormId(null);
        entity.setBusinessType(businessType);
        entity.setDel(BasicConstant.ZERO);
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        switch (xbbRefTypeEnum){
            case CUSTOMER_MANAGEMENT:
            case CLUE:
            case CONTACT:
                List<String> initAttrList = Arrays.asList(StringConstant.NAME,StringConstant.PHONE);
                for (String attr : initAttrList){
                    List<RecheckAttrRulePojo> noRepeatRulePojoList = new ArrayList<>();
                    RecheckFormRulePojo noRepeatFormRulePojo = new RecheckFormRulePojo();
                    //单元格 字段级别规则,新建不允许重复规则
                    noRepeatRulePojoList.add(new RecheckAttrRulePojo(0,attr,attr,0L, RecheckMatchWayEnum.EXACT_MATCH.getCode(), xbbRefTypeEnum.getCode()));
                    setRecheckFormRulePojo(noRepeatFormRulePojo,businessType,noRepeatRulePojoList);
                    noRepeatRule.add(noRepeatFormRulePojo);
                    List<RecheckAttrRulePojo> checkToolRulePojoList = new ArrayList<>();
                    //查重工具规则
                    RecheckFormRulePojo checkToolFormRulePojo = new RecheckFormRulePojo();
                    checkToolRulePojoList.add(new RecheckAttrRulePojo(0,attr,attr,0L,RecheckMatchWayEnum.FUZZY_MATCH.getCode(), xbbRefTypeEnum.getCode()));
                    setRecheckFormRulePojo(checkToolFormRulePojo,businessType,checkToolRulePojoList);
                    checkToolRule.add(checkToolFormRulePojo);
                }
                entity.setNormalEnable(BasicConstant.ONE);
                entity.setCheckToolRule(JSON.toJSONString(checkToolRule));
                entity.setNoRepeatRule(JSON.toJSONString(noRepeatRule));
                return entity;
            case SALES_OPPORTUNITY:
                List<String> opportunityAttrList = Arrays.asList(SalesOpportunityEnum.NAME.getAttr(),SalesOpportunityEnum.SERIAL_NO.getAttr());
                for (String attr : opportunityAttrList){
                    RecheckFormRulePojo noRepeatFormRulePojo = new RecheckFormRulePojo();
                    List<RecheckAttrRulePojo> noRepeatRulePojoList = new ArrayList<>();
                    noRepeatRulePojoList.add(new RecheckAttrRulePojo(0,attr,attr,0L,RecheckMatchWayEnum.EXACT_MATCH.getCode(), xbbRefTypeEnum.getCode()));
                    noRepeatFormRulePojo.setOpportunity(noRepeatRulePojoList);
                    noRepeatRule.add(noRepeatFormRulePojo);
                }
                entity.setNormalEnable(BasicConstant.ZERO);
                entity.setCheckToolRule(JSON.toJSONString(checkToolRule));
                entity.setNoRepeatRule(JSON.toJSONString(noRepeatRule));
                return entity;
            default:
                break;
        }
        return entity;
    }



    /**
     * @description 赋值不同业务的字段重复规则
     * @author yanglei
     * @date 2022/11/15 16:32
     * @param recheckFormRulePojo
     * @param businessType
     * @param attrRulePojoList
     */
    public void setRecheckFormRulePojo(RecheckFormRulePojo recheckFormRulePojo,Integer businessType,List<RecheckAttrRulePojo> attrRulePojoList){
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CUSTOMER_MANAGEMENT:
                recheckFormRulePojo.setCustomer(attrRulePojoList);
                break;
            case CLUE:
                recheckFormRulePojo.setClue(attrRulePojoList);
                break;
            case CONTACT:
                recheckFormRulePojo.setContact(attrRulePojoList);
                break;
            case SALES_OPPORTUNITY:
                recheckFormRulePojo.setOpportunity(attrRulePojoList);
                break;
            default:
                break;
        }
    }

}
